package com.cn.chaomeng.constant;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cn.chaomeng.model.weixin.User;
import com.cn.chaomeng.utils.HttpUtils;
import com.cn.chaomeng.utils.MD5;
import org.apache.log4j.Logger;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author 范中燊
 * @version V1.0
 * @Title: 微信常量
 * @Package ${package_name}
 * @Description: TODO
 * @date ${date} ${time}
 */
public class WxConstant
{

    private final static Logger logger = Logger.getLogger(WxConstant.class);

    //    public static String APPID = "wxda8d67754b50313a";
    public static String APPID = "wxbfa722071704fa59";

    public static String VERSION = "1.0";

    public static String TEST_HOST = "http://wxapi.3cuc.com.cn/";

    public static String HOST = "http://wxapi.3cuc.com.cn/";

    public static String ACCESS_TOKEN = "wechat/getaccesstoken";

    public static String WX_OPENID = "wechat/gettokenbycode";

    public static String WX_USER = "wechat/getuserinfo";

    public static String WX_QRCODE = "wechat/getQrcode";

    public static String WX_STATE = "chaomeng";

    private static String getUrl(String appId, String Url)
        throws UnsupportedEncodingException
    {
        String UrlEncoder = URLEncoder.encode(Url);
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri="
            + UrlEncoder + "&response_type=code&scope=snsapi_base&state=" + WX_STATE + "#wechat_redirect";
        return url;
    }

    /**
     * 获取openId
     *
     * @param code
     * @return
     */
    public static String getOpenIdByCode(String code)
        throws Exception
    {
        /** 组装参数 **/
        Map prarmMap = new HashMap();
        prarmMap.put("appid", APPID);
        prarmMap.put("version", VERSION);

        /** assci排序 **/
        String prarmString = HttpUtils.formatUrlMap(prarmMap, true, false);
        String url = WxConstant.TEST_HOST + WxConstant.WX_OPENID;
        prarmMap.put("sign", MD5.getMD5Str(prarmString));
        prarmMap.put("code", code);

        /** 获取获取返回值 **/
        String resString = HttpUtils.post(url, prarmMap);

        logger.info("获取openId：" + resString);

        JSONObject tokenJson = JSON.parseObject(resString);

        if (!tokenJson.getBoolean("result"))
        {
            return null;
        }

        return tokenJson.getJSONObject("msg").getString("openid");
    }

    public static User getWxUser(String openId)
        throws Exception
    {
        /** 组装参数 **/
        Map prarmMap = new HashMap();
        prarmMap.put("appid", APPID);
        prarmMap.put("version", VERSION);
        /** assci排序 **/
        String prarmString = HttpUtils.formatUrlMap(prarmMap, true, false);
        String url = HOST + WxConstant.WX_USER;
        prarmMap.put("sign", MD5.getMD5Str(prarmString));
        prarmMap.put("openid", openId);
        /** 获取获取返回值 **/
        String resString = HttpUtils.post(url, prarmMap);

        logger.info("获取用户信息：" + resString);

        JSONObject tokenJson = JSON.parseObject(resString);

        if (!tokenJson.getBoolean("result"))
        {
            return refreshToken(openId);
        }

        return JSONObject.parseObject(tokenJson.getString("data"), User.class);
    }

    private synchronized static User refreshToken(String openId)
        throws Exception
    {
        /** 组装参数 **/
        Map prarmMap = new HashMap();
        prarmMap.put("appid", APPID);
        prarmMap.put("version", VERSION);
        /** assci排序 **/
        String prarmString = HttpUtils.formatUrlMap(prarmMap, true, false);
        String url = HOST + WxConstant.WX_USER;
        prarmMap.put("sign", MD5.getMD5Str(prarmString));
        prarmMap.put("openid", openId);
        prarmMap.put("refresh_token ", 1);
        /** 获取获取返回值 **/
        String resString = HttpUtils.post(url, prarmMap);

        logger.info("获取用户信息：" + resString);

        JSONObject tokenJson = JSON.parseObject(resString);

        if (!tokenJson.getBoolean("result"))
        {
            return null;
        }

        return JSONObject.parseObject(tokenJson.getString("data"), User.class);
    }

    /**
     * 获取微信带参数二维码接口
     *
     * @param appID
     * @param type
     * @param scene
     * @return
     */
    public static Object getQrCode(String appID, String type, String scene)
        throws Exception
    {
        /** 组装参数 **/
        Map prarmMap = new HashMap();
        prarmMap.put("appid", appID);
        prarmMap.put("version", VERSION);

        /** assci排序 **/
        String prarmString = HttpUtils.formatUrlMap(prarmMap, true, false);
        String url = HOST + WxConstant.WX_QRCODE;
        prarmMap.put("sign", MD5.getMD5Str(prarmString));
        prarmMap.put("type", type);
        prarmMap.put("scene", scene);
        /** 获取获取返回值 **/
        String resString = HttpUtils.post(url, prarmMap);

        System.out.println(resString);

        JSONObject tokenJson = JSON.parseObject(resString);

        if (!tokenJson.getBoolean("result"))
        {
            return null;
        }

        return JSONObject.parseObject(tokenJson.getString("data")).getString("encodeImage");
    }

    public static Map<String, String> sign(String jsapi_ticket, String url)
    {
        Map<String, String> ret = new HashMap<String, String>();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String string1;
        String signature = "";

        //注意这里参数名必须全部小写，且必须有序
        string1 = "jsapi_ticket=" + jsapi_ticket +
            "&noncestr=" + nonce_str +
            "&timestamp=" + timestamp +
            "&url=" + url;
//        System.out.println(string1);

        try
        {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }

        ret.put("url", url);
        ret.put("jsapi_ticket", jsapi_ticket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);

        return ret;
    }

    private static String byteToHex(final byte[] hash)
    {
        Formatter formatter = new Formatter();
        for (byte b : hash)
        {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    private static String create_nonce_str()
    {
        return UUID.randomUUID().toString();
    }

    private static String create_timestamp()
    {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

    public static void main(String[] args)
    {
        try
        {
//            String jsapi_ticket = "jsapi_ticket";
//
//            // 注意 URL 一定要动态获取，不能 hardcode
//            String url = "http://example.com";
//            Map<String, String> ret = sign(jsapi_ticket, url);
//            for (Map.Entry entry : ret.entrySet()) {
//                System.out.println(entry.getKey() + ", " + entry.getValue());
//            }

//            getOpenIdByCode("021JVuL71L8G4T15mrM712xEL71JVuLC");

            System.out.println(getUrl(APPID, "http://b.cmfspay.com/pay/weixin/login"));

//            System.out.println("data:image/jpeg;base64,"+getQrCode(APPID,"2","1"));

//            BigDecimal b1 = new BigDecimal(Double.toString(13));
//            BigDecimal b2 = new BigDecimal(Double.toString(12.0));
//          System.out.println(b1.add(b2).doubleValue());

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
